package br.com.caelum.dao;

import br.com.caelum.util.HibernateUtil;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

public abstract class GenericDao<T> {

    protected abstract Class<T> getClassePersistente();

    public void salvar(T objeto) {
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        sessao.saveOrUpdate(objeto);
        sessao.getTransaction().commit();
    }

    public void excluir(T objeto) {
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        sessao.delete(objeto);
        sessao.getTransaction().commit();
    }

    public T buscarPorId(int id) {
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        T objeto = (T) sessao.createCriteria(getClassePersistente()).
                add(Restrictions.eq("id", id)).uniqueResult();
        sessao.getTransaction().commit();
        return objeto;
    }

    public List<T> buscarPorNome(String nome) {
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        List<T> lista =  sessao.createCriteria(getClassePersistente()).
                add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE)).list();
        sessao.getTransaction().commit();
        return lista;
    }

    public List<T> listarTodos() {
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        Criteria criteria = sessao.createCriteria(getClassePersistente());
        criteria.addOrder(Order.asc("id"));
        List<T> lista = criteria.list();
        sessao.getTransaction().commit();
        return lista;
    }

    public void recarrega(T objeto){
        Session sessao = HibernateUtil.getSessionFactory().getCurrentSession();
        sessao.beginTransaction();
        sessao.refresh(objeto);
        sessao.beginTransaction().commit();
    }
}